﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Omniture.Studio.Objects
{
	internal class ListViewHelper
	{
		#region Class Members

		private int lastSort = -1;
		private ListView _listView = null;
		private ListViewColumnSorter _lvwColumnSorter = null;

		#endregion

		#region Constructor

		public ListViewHelper(ListView listView)
		{
			if (listView == null)
				throw new Exception("The listview control cannot be null!");

			_listView = listView;
			_lvwColumnSorter = new ListViewColumnSorter();
			_listView.ListViewItemSorter = _lvwColumnSorter;
			_listView.ColumnClick += new ColumnClickEventHandler(listView_ColumnClick);
		}

		#endregion

		#region Event Handlers

		private void listView_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if (e.Column == _lvwColumnSorter.SortColumn)
			{
				// Reverse the current sort direction for this column.
				if (_lvwColumnSorter.Order == SortOrder.Ascending)
					_lvwColumnSorter.Order = SortOrder.Descending;
				else
					_lvwColumnSorter.Order = SortOrder.Ascending;
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				_lvwColumnSorter.SortColumn = e.Column;
				_lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			_listView.Sort();

		}

		#endregion

		#region Comparer Class

		/// <summary>
		/// This class is an implementation of the 'IComparer' interface.
		/// </summary>
		private class ListViewColumnSorter : IComparer
		{
			/// <summary>
			/// Specifies the column to be sorted
			/// </summary>
			private int _columnToSort;
			/// <summary>
			/// Specifies the order in which to sort (i.e. 'Ascending').
			/// </summary>
			private SortOrder _orderOfSort;
			/// <summary>
			/// Case insensitive comparer object
			/// </summary>
			private CaseInsensitiveComparer ObjectCompare;

			/// <summary>
			/// Class constructor.  Initializes various elements
			/// </summary>
			public ListViewColumnSorter()
			{
				// Initialize the column to '0'
				_columnToSort = 0;

				// Initialize the sort order to 'none'
				_orderOfSort = SortOrder.None;

				// Initialize the CaseInsensitiveComparer object
				ObjectCompare = new CaseInsensitiveComparer();
			}

			/// <summary>
			/// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
			/// </summary>
			/// <param name="x">First object to be compared</param>
			/// <param name="y">Second object to be compared</param>
			/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
			public int Compare(object x, object y)
			{
				int compareResult;
				ListViewItem listviewX, listviewY;

				// Cast the objects to be compared to ListViewItem objects
				listviewX = (ListViewItem)x;
				listviewY = (ListViewItem)y;

				// Compare the two items
				compareResult = ObjectCompare.Compare(listviewX.SubItems[_columnToSort].Text, listviewY.SubItems[_columnToSort].Text);				
				
				// Calculate correct return value based on object comparison
				if (_orderOfSort == SortOrder.Ascending)
				{
					// Ascending sort is selected, return normal result of compare operation
					return compareResult;
				}
				else if (_orderOfSort == SortOrder.Descending)
				{
					// Descending sort is selected, return negative result of compare operation
					return (-compareResult);
				}
				else
				{
					// Return '0' to indicate they are equal
					return 0;
				}
			}

			/// <summary>
			/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
			/// </summary>
			public int SortColumn
			{
				set { _columnToSort = value; }
				get { return _columnToSort; }
			}

			/// <summary>
			/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
			/// </summary>
			public SortOrder Order
			{
				set { _orderOfSort = value; }
				get { return _orderOfSort; }
			}

		}

		#endregion

	}

}